整理データ原則(tidy text principal)は, データの効果的で 簡単な処理のためのに威力を発揮します. それはテキストを扱うときも同様です. Hadley Wickhamによると整理データは次の決められた構造を持ちます.
これに準拠している整理テキスト形式とは, 1行に1つのトークンからなる表と 定義する. トークンとはテキストとして意味を持つ単位です. データによって異なり, 例えば単語, センテンス, 段落があります.
整理テキスト形式でデータを整理することで, dplyr等のtidyverseパッケージによって 処理ができ, テキストの分析, 探索が効果的にお粉ます.
# load libs
libs <- c( "tidyverse", "tidytext", "janeaustenr", "gutenbergr", "scales" )
for( lib in libs ) {
if(!require(lib, character.only = TRUE)) {
install.packages(lib)
library(lib, character.only = TRUE)
}
} まずは文字列ベクトルを持つデータフレームを作成する
text <- c("Because I could not stop for Death -",
"He kindly stopped for me -",
"The Carriage held but just Ourselves -",
"and Immortality")
text_df <- data_frame(
line = seq_along(text),
text = text
)
text_dfこの状態はまだ整理テキスト分析に向かない. 各行が単語を連結したものであるためである. これを1行を1文書の1トークンの形式に変換する必要がある.
テキストをトークンに分割するための関数もあるが, 整理データ構造に変換する関数unnest_tokensがある.
text_df %>%
unnest_tokens(word, text)第1引数のwordは文書のトークンをどのレベルまで下げるかという指定であり, 第2引数のtextは対象のトークンを持つ列名である.
original_books <-
austen_books() %>%
group_by(book) %>%
mutate(
linenumber = row_number(),
chapter = cumsum(
str_detect(
text,
regex("^chapter [\\divxlc]", ignore_case = TRUE) # \dはdigitのシンボル
)
)
) %>%
ungroup()
original_books先ほどと同様に, textを単語単位のトークンにunnestを行う.
tidy_books <-
original_books %>%
unnest_tokens(word, text)
tidy_booksテキスト分析ではストップワードを除いて分析を行います. 次のようにしてストップワードを除きます.
data(stop_words)
tidy_books <-
tidy_books %>%
anti_join(stop_words, by = "word") # tidy_textのstop_wordsデータセットを使う
tidy_books集計して最頻出単語を探し, グラフで確認する.
tidy_books %>%
count(word, sort = TRUE) %>%
filter(n > 600) %>%
mutate(word = reorder(word, n)) %>%
ggplot(aes(word, n)) +
geom_col() + # stat = identityのgeom_bar
xlab(NULL) +
coord_flip() +
theme_light()gutenbergパッケージを使うと, Project Gutenbergコレクションの パブリックドメイン作品にアクセスすることができる.
テキストマイニングではまず単語の出現頻度を比較する.
hgwells <-
gutenberg_download(c(35, 36, 5230, 159))## Determining mirror for Project Gutenberg from http://www.gutenberg.org/robot/harvest
## Using mirror http://aleph.gutenberg.org
tidy_hgwells <-
hgwells %>%
unnest_tokens(word, text) %>%
anti_join(stop_words, by = "word")ダウンロードしたH・Gウェルズの4作品の最頻出語を調べてみる.
tidy_hgwells %>%
count(word, sort = TRUE)次にプロンテ姉妹の作品を調べてみる.
target_book_ids <- c(1260, 768, 969, 9182, 767)
bronte <- gutenberg_download(target_book_ids)
tidy_bronte <-
bronte %>%
unnest_tokens(word, text) %>%
anti_join(stop_words)## Joining, by = "word"
tidy_bronte %>%
count(word, sort = TRUE)次に3のデータフレームを結合して調べてみる.
frequency <-
bind_rows(
mutate(tidy_bronte, author = "Brontë Sisters"),
mutate(tidy_hgwells, author = "H.G. Wells"),
mutate(tidy_books, author = "Jane Austen")) %>%
mutate(word = str_extract(word, "[a-z']+")) %>%
count(author, word) %>%
group_by(author) %>%
mutate(proportion = n / sum(n)) %>%
select(-n) %>%
spread(author, proportion) %>%
gather(author, proportion, `Brontë Sisters`:`H.G. Wells`)結果をプロットしてみる.
ggplot(frequency,
aes(x = proportion, y = `Jane Austen`,
color = abs(`Jane Austen` - proportion))) +
geom_abline(color = "gray40", lty = 2) +
geom_jitter(alpha = .1, size = 2.5, width = .3, height = .3) +
geom_text(aes(label = word), check_overlap = TRUE, vjust = 1.5) +
scale_x_log10(labels = percent_format()) +
scale_y_log10(labels = percent_format()) +
scale_color_gradient(limits = c(0, .0011),
low = "darkslategray4", high = "gray75") +
facet_wrap( ~ author, ncol = 2) +
theme(legend.position = "none") +
labs(y = "Jane Austen", x = "NULL")## Warning: Removed 41357 rows containing missing values (geom_point).
## Warning: Removed 41359 rows containing missing values (geom_text).
最後に相関検定にかけてみる.
cor.test(
data = frequency[frequency$author == "Bronte Sisters",],
~ proportion + `Jane Austen`
)##
## Pearson's product-moment correlation
##
## data: proportion and Jane Austen
## t = 119.65, df = 10404, p-value < 2.2e-16
## alternative hypothesis: true correlation is not equal to 0
## 95 percent confidence interval:
## 0.7527869 0.7689641
## sample estimates:
## cor
## 0.7609938
cor.test(
data = frequency[frequency$author == "H.G. Wells",],
~ proportion + `Jane Austen`
)##
## Pearson's product-moment correlation
##
## data: proportion and Jane Austen
## t = 36.441, df = 6053, p-value < 2.2e-16
## alternative hypothesis: true correlation is not equal to 0
## 95 percent confidence interval:
## 0.4032800 0.4445987
## sample estimates:
## cor
## 0.4241601